/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：CompositeModel.js<br>
 * 日期：2016年9月19日<br>
 * 作者: 王志远<br>
 * 功能：组合模型<br>
 * 
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

window.makeNamespace(window,"Rainier.UI.V2");

/**
 * 类型名称：Rainier.UI.V2.CompositeModel<br>
 * 类型功能：组合模型<br>
 */
Rainier.UI.V2.CompositeModel = Rainier.UI.V2.AbstractModel.extend({
	
	NAME : "Rainier.UI.V2.CompositeModel",
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.init<br>
	 * 函数功能：构造函数<br>
	 * 参数输入:property属性对象<br>
	 * {
	 * 	   type:Rainier.UI.V2.CompositeModel,
	 * 	   id:'111-111-111-111',
	 * 	   
	 *     uiProperty:{
	 * 	   		x:500,
	 * 			y:500,
	 * 			width:50,
	 * 			height:50,
	 * 			bgColor:'#FF00FF'
	 *     },
	 *     
	 *     modelProperty:{
	 *     		type:Rainier.UI.V2.CompositeModel
	 *     		name:'模型1',
	 *     	 	locator{
	 *     			type:draw2d.layout.locator.XYAbsPortLocator,
	 *     			x:20,
	 *     			y:20
	 *     		},
	 *     }
	 *     
     *     portModels:[
	 *     		{
	 *     			type:Rainier.UI.V2.HybridPortModel,
	 *     			id:'111-111-111-112',
	 *     			uiProperty:{
	 * 					width:10,
	 * 					height:10,
	 * 					bgColor:'#FF00FF'		
	 *     			},
	 *     
	 *     			modelProperty:{
	 *     				name:"port1"
	 *     				locator{
	 *     					type:draw2d.layout.locator.XYAbsPortLocator,
	 *     					x:20,
	 *     					y:20
	 *     				},
	 *     			},
	 *     		},
	 *     
	 *     		{
	 *     			type:Rainier.UI.V2.HybridPortModel,
	 *     			id:'111-111-111-113',
	 *     			uiProperty:{
	 * 					width:10,
	 * 					height:10,
	 * 					bgColor:'#FF00FF'		
	 *     			},
	 *     
	 *     			modelProperty:{
	 *     				name:"port2"
	 *     				locator{
	 *     					type:draw2d.layout.locator.XYAbsPortLocator,
	 *     					x:20,
	 *     					y:20
	 *     				},
	 *     			},
	 *     		}

	 *     ],
	 *     
	 *     childModels:[
	 *     		{
	 *     			type:Rainier.UI.V2.CompositeModel,
	 *     			uiProperty:{...},
	 *     			modelProperty:{...},
	 *     			portModels:{...},
	 *     			childModels:{...}
	 *     		},
	 *     	    {
	 *     			type:Rainier.UI.V2.CompositeModel,
	 *     			uiProperty:{...},
	 *     			modelProperty:{...},
	 *     			portModels:{...},
	 *     			childModels:{...}
	 *     		},
	 *     ]
	 *     
	 * }
	 * 异常信息：无<br>
	 */
	init : function(property){
		var dummy = jQuery.extend(true,{},property);
		this._super(dummy);
		this.inputPorts = new draw2d.util.ArrayList();
		this.outputPorts= new draw2d.util.ArrayList();
		this.hybridPorts= new draw2d.util.ArrayList();
		this.connections= new draw2d.util.ArrayList();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.serializeToJson<br>
	 * 函数功能：将对象串行化为Json对象<br>
	 * 函数返回：json对象<br>
	 * 异常信息：无<br>
	 */
	serializeToJson : function(){
		var json = this._super();
		
		//保存子器件
		var children = this.getChildren();
		if(children.length > 0){
			json.componentList	= [];
		}
		
		if(json.componentList){
			$.each(children,function(i,child){
				json.componentList.push(child.serializeToJson());			
			});			
		}
				
		//保存端口
		if(this.inputPorts.getSize() > 0 ||
				this.hybridPorts.getSize() > 0 ||
					this.outputPorts.getSize() > 0
				){
			json.portList = [];			
		}
		
		if(json.portList){
			this.inputPorts.each(function(i,port){
				json.portList.push(port.serializeToJson());
			});
			this.hybridPorts.each(function(i,port){
				json.portList.push(port.serializeToJson());
			});
			this.outputPorts.each(function(i,port){
				json.portList.push(port.serializeToJson());
			});			
		}
		
		//保存连接
		if(this.connections.getSize() > 0){
			json.connectionList = [];			
		}
		
		if(json.connectionList){
			this.connections.each(function(i,conn){
				json.connectionList.push(conn.serializeToJson());
			});			
		}
		
		return json;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.clone<br>
	 * 函数功能：对象拷贝<br>
	 * 函数功能：当考虑其对应的深拷贝时：关注对应port的入度和初度。此处也可留给conntion来处理<br>
	 * 函数功能：port的入度和初度的修改，当使用connection拷贝时处理<br>
	 * 参数输入：无<br>
	 * 参数输出：无<br>
	 * 函数返回：Rainier.UI.V2.CompositeModel<br>
	 * 异常信息：无<br>
	 */
	clone : function(){
		if(!this.duplicate){
			this.duplicate = eval('new '+this.NAME+'(this.getProperty())');
			//this.duplicate = new Rainier.UI.V2.CompositeModel(this.getProperty());
		}
		var _this = this.duplicate;
		_this.inputPorts.clear();
		this.inputPorts.each(function(j,port){
			_this.inputPorts.add((port.duplicate)?port.duplicate:port.clone());
			port.duplicate.setParent(_this);
		});
		_this.outputPorts.clear();
		this.outputPorts.each(function(j,port){
			_this.outputPorts.add((port.duplicate)?port.duplicate:port.clone());
			port.duplicate.setParent(_this);
		});
		_this.hybridPorts.clear();
		this.hybridPorts.each(function(j,port){
			_this.hybridPorts.add((port.duplicate)?port.duplicate:port.clone());
			port.duplicate.setParent(_this);
		});
		
		//处理当前model的连线时，需要特殊处理
		this.connections.each(function(j,connection){
			_this.connections.add((connection.duplicate)?connection.duplicate:connection.clone());
		});
		return this.duplicate;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.clearDuplicate<br>
	 * 函数功能：清除当前元件的 副本<br>
	 * 参数输入：无<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	clearDuplicate : function(){
		var _this = this.duplicate;
		this.inputPorts.each(function(j,port){
			port.clearDuplicate();
		});

		this.outputPorts.each(function(j,port){
			port.clearDuplicate();
		});

		this.hybridPorts.each(function(j,port){
			port.clearDuplicate();
		});
		this.connections.each(function(j,connection){
			connection.clearDuplicate();
		});
		this.duplicate = null;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.removeChildModel<br>
	 * 函数功能：删除子模型<br>
	 * 参数输入：model:Rainier.UI.V2.CompositeModel<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	removeChildModel : function(model,needCommandRequest){
		//方法一：解决删除图元问题，删除当 前图元和与图元有关的连线
		var _this = this;
		if(model instanceof Rainier.UI.V2.DeviceModel){
			
			this.deleteModelLabel(model);
			
			var connList 				= new draw2d.util.ArrayList();		//存储和当前model关联的连线
			var modelPortList	 		= new draw2d.util.ArrayList();		//存储deviceModel上的port组件
			var modelConnList	 		= new draw2d.util.ArrayList();		//存储deviceModel上的connection组件
			var deleteConnInfoStack		= new draw2d.util.ArrayList();		//删除连线的stack
			var connPortInfoList		= new draw2d.util.ArrayList();
			//第一步：获取device关联的连线和port
			modelPortList = model.getOwnPorts();
			modelConnList = model.getAssociationConnection();
			
			//获取与连线有关的连线
			modelConnList.each(function(index,conn){
				var connChildrenList = conn.getBranchConnection();
				connList.addAll(connChildrenList);
				//记录所有关联主连线的sourcePort和TargetPort;
				var portInfo = {};
				portInfo.sourcePort = conn.getSourcePort();
				portInfo.targetPort = conn.getTargetPort();
				connPortInfoList.add(portInfo);
			});
			
			//第二步：去除重复的连线
			var uniqConnList = this.uniqConnList(connList);
			
			//第三步：删除所有的连线
			_this.deleteConnection(uniqConnList,deleteConnInfoStack);
			
			connPortInfoList.each(function(index,portInfo){
				_this.resetConnectionPortValue(portInfo.sourcePort,portInfo.targetPort);
			});
			
			//第四步：删除所有的节点
			modelPortList.each(function(i,port){
				model.removePort(port);
			});
			
			var obj = null;
			var deleteModelInfo = null;
			var sObjId = model.getUuid();
			
			//第五步：删除model
			//如果model是虚拟仪器：
			if(model instanceof Rainier.UI.V2.VirtualModel){
				model.closeCvi();
			}
			
			if(this.m_aChildren[sObjId]){
				obj = this.m_aChildren[sObjId];
				var newValue 				= {};
				newValue.model 				= obj;
				newValue.ports 				= modelPortList;
				newValue.deleteConnInfoStack= deleteConnInfoStack;
				newValue.needCommandRequest = needCommandRequest;
				
				delete this.m_aChildren[sObjId];
				this.firePropertyChange(
						Rainier.Basic.CompositeObject.SC_S_EVENT_REMOVE_CHILD, 
						null, 
						newValue
				);
				deleteModelInfo = newValue;
			}
			
			//返回删除model的所有信息；
			return deleteModelInfo;
		}
		
		if(model instanceof Rainier.UI.V2.JointModel){
			var jointPort =  model.getHybridPorts().get(0);
			model.removePort(jointPort);
			
			var sObjId = model.getUuid();
			if(this.m_aChildren[sObjId]){
				var obj 					= this.m_aChildren[sObjId];
				var newValue 				= {};
				newValue.model	 			= obj;
				newValue.needCommandRequest = needCommandRequest;
				delete this.m_aChildren[sObjId];
				this.firePropertyChange(
						Rainier.Basic.CompositeObject.SC_S_EVENT_REMOVE_CHILD, 
						null, 
						newValue
				);
			}	
		}
		
		
		//方法二：本段程序为递归删除方法，存在一定缺陷undo操作不易实现
		/*Rainier.UI.V2.CompositeModel.reursiveRemoveChildModel(model,function(child){
			if(child instanceof Rainier.UI.V2.CompositeModel){
				
				var inputPorts = child.getInputPorts();
				var outputPorts= child.getOutputPorts();
				var hybridPorts= child.getHybridPorts();
				var connections= child.getConnections();
				
				connections.each(function(i,p){
					child.removeConnection(p);					
				},false);
				
				inputPorts.each(function(i,p){
					child.removePort(p);					
				},false);
				
				outputPorts.each(function(i,p){
					child.removePort(p);					
				},false);
				
				hybridPorts.each(function(i,p){
					child.removePort(p);					
				},false);
			}
		});
		*/
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.addChildModel<br>
	 * 函数功能：添加子模型<br>
	 * 参数输入：model:Rainier.UI.V2.CompositeModel<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	addChildModel : function(model,needCommandRequest){
		
		if(this.m_aChildren[model.getUuid()]){
			return;
		}
		
		if(model instanceof Rainier.UI.V2.DeviceModel){
			this.addModelLabel(model);
		}
		
		var newValue = {};
		newValue.model = model;
		newValue.needCommandRequest = needCommandRequest;
		
		this.m_aChildren[model.getUuid()] = model;
		model.setParent(this);
		this.firePropertyChange(
				Rainier.Basic.CompositeObject.SC_S_EVENT_ADD_CHILD, 
				null, 
				newValue
		);
	},

	/**
	 * @名称   addModelLabel
	 * @功能   为model的label赋值
	 * @author 杨顺强
	 * @data   2017-07-07
	 * @param  {[type]}   model [description]
	 */
	addModelLabel : function(model){
		if(this.context){
			var context      = this.context;
			var label        = model.getProperty().modelProperty.label;
			var defaultLabel = model.getProperty().modelProperty.defaultLabel;
			if(!context.labelList['nameList']){
				context.labelList['nameList'] = [];
			}
			if(!label && defaultLabel){
				//只有defaultLabel 存在说明是添加元件
				if(!context.labelList[defaultLabel+'_number']){
					context.labelList[defaultLabel+'_number'] = 1;
				}

				var labelName = defaultLabel + context.labelList[defaultLabel + "_number"];
				while(context.labelList['nameList'].indexOf(labelName) > -1){
					context.labelList[defaultLabel+'_number'] += 1;
					labelName = defaultLabel + context.labelList[defaultLabel + "_number"];
				}

				context.labelList['nameList'].push(labelName);
				context.labelList[defaultLabel+'_number'] += 1;
				model.getProperty().modelProperty.label    = labelName;

			}else if(label && defaultLabel){
				//两者同时存在，说明是恢复实验
				var labelName = label;
				if(context.labelList['nameList'].indexOf(labelName) > -1){
					//说明是复制粘贴元件

					var labelName = defaultLabel + context.labelList[defaultLabel + "_number"];
					while(context.labelList['nameList'].indexOf(labelName) > -1){
						context.labelList[defaultLabel+'_number'] += 1;
						labelName = defaultLabel + context.labelList[defaultLabel + "_number"];
					} 

					context.labelList['nameList'].push(labelName);
					context.labelList[defaultLabel+'_number'] += 1;
					model.getProperty().modelProperty.label    = labelName;
				}else{
					var labelNumber = label.replace(/[^0-9]+/g,"");
					labelNumber     = labelNumber ? parseInt(labelNumber) : 1; 
					if(!context.labelList[defaultLabel+'_number']){
						context.labelList[defaultLabel+'_number'] = labelNumber;
					}else{
						var number = context.labelList[defaultLabel+'_number'];
						if(labelNumber > number){
							context.labelList[defaultLabel+'_number'] = number;
						}
					}
					context.labelList['nameList'].push(label);	
				}
			}
		}
	},
		
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.addModelLabel<br>
	 * 函数功能：增加模型标签，修改标签序号，添加context名称列表<br>
	 * 参数输入：model ： 元件模型<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	addModelLabel_bak : function(model){		
		if(this.context){
	    	var context 	= this.context;
	    	var label   	= model.getProperty().modelProperty.label;
	    	if(!label){
	    		label = model.getProperty().modelProperty.defaultLabel;
	    	}
	    	if(label){
		    	
				if(!context.labelList['nameList']){
		    	   var list = [];
		    	   context.labelList['nameList'] = list;
				}
				
		    	var defaultLabel   	= model.getProperty().modelProperty.defaultLabel;
		    	if(!defaultLabel){
		    		model.getProperty().modelProperty.defaultLabel = label;
		    		defaultLabel = label;
		    	}
	    		var exist = 1;
	    		if(defaultLabel !== label){
	    			if(context.labelList['nameList']){
	        			if(context.labelList['nameList'].indexOf(label) < 0){
	        				exist = 0;
	        			}
	    			}
	    		}
				if(exist === 1){
					if(!context.labelList[defaultLabel] ){
						context.labelList[defaultLabel] = 0;
		    		}
	    			var count = parseInt(context.labelList[defaultLabel]) + 1;
					var name  = defaultLabel + count;
					
					while(context.labelList['nameList'].indexOf(name) >= 0){
	    				count += 1;
	    				name = defaultLabel + count;
	    			}
	    			context.labelList[defaultLabel] = count;
	    			label = defaultLabel + context.labelList[defaultLabel];
				}
				context.labelList['nameList'].push(label);
				model.getProperty().modelProperty.label = label;
	    	}
    	}		
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.deleteModelLabel<br>
	 * 函数功能：从context名称列表中删除<br>
	 * 参数输入：model ： 元件模型<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	deleteModelLabel : function(model){

		if(this.context){
	    	var context 	= this.context;
	    	var label   	= model.getProperty().modelProperty.label;
	    	
			if(context.labelList['nameList']){
	    	   var index = context.labelList['nameList'].indexOf(label);
	    	   context.labelList['nameList'].splice(index,1);
			}
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.connectBySourceTargetProperty<br>
	 * 函数功能：通过源端口Model，目标端口Model和属性实现连接<br>
	 * 参数输入：sourceModel:PortModel<br>
	 * 参数输入：targetModel:PortModel<br>
	 * 参数输入：property:Object<br>
	 * 参数输入：needCommandRequest:boolean<br>
	 * 函数返回：connection<br>
	 * 异常信息：无<br>
	 */
	connectBySourceTargetProperty : function(sourceModel,targetModel,property,needCommandRequest){
		return this.connect(sourceModel,targetModel,property,needCommandRequest);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.connectByProperty<br>
	 * 函数功能：通过属性参数进行连接<br>
	 * 参数输入：property<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	connectByProperty : function(context,property,needCommandRequest){
		var uiProperty    = property.uiProperty;
		var modelProperty = property.modelProperty;
		var sourceId      = modelProperty.source_id;
		var targetId	  = modelProperty.target_id;
		var sourceModel   = null;
		var targetModel   = null;
		
		var ctx = context;
		sourceModel = ctx.findModelById(sourceId);
		targetModel = ctx.findModelById(targetId);
		
		if(sourceModel && targetModel){
			return this.connect(sourceModel,targetModel,property,needCommandRequest);
		}
		return null;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.connect<br>
	 * 函数功能：添加链接<br>
	 * 参数输入：sourcePort:Rainier.UI.V2.AbstractPortModel<br>
	 * 参数输入：targetPort:Rainier.UI.V2.AbstractPortModel<br>
	 * 参数输入：connProperty:
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	connect : function(sourcePort,targetPort,connProperty,needCommandRequest){
		var conn = new Rainier.UI.V2.ConnectionModel(connProperty);
		
		conn.attachSourcePort(sourcePort);
		sourcePort.attachOutgoing(conn);
		
		conn.attachTargetPort(targetPort);
		targetPort.attachIncoming(conn);
		
		this.connections.add(conn);
		conn.setParent(this);
		
		
		var newValue = {};
		newValue.model = conn;
		newValue.needCommandRequest = needCommandRequest;
		
		var event = Rainier.UI.V2.CompositeModel.MODEL_EVENT_ADD_CONNECTION;
		this.firePropertyChange(
				event, 
				null, 
				newValue
		);
		
		this.setConnectionPortValue(sourcePort,targetPort);
		return conn;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.addConnection<br>
	 * 函数功能：添加连接<br>
	 * 参数输入：connection:Rainier.UI.V2.ConnectionModel<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	addConnection : function(conn,needCommandRequest){
		console.log("addconn")
		this.connections.add(conn);
		conn.setParent(this);
		
		var newValue = {};
		newValue.model = conn;
		newValue.needCommandRequest = needCommandRequest;
		
		var event = Rainier.UI.V2.CompositeModel.MODEL_EVENT_ADD_CONNECTION;
		this.firePropertyChange(
				event, 
				null, 
				newValue
		);
		this.setConnectionPortValue(conn.sourcePort,conn.targetPort);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.deleteConnectionModel<br>
	 * 函数功能：删除连线model的详细信息<br>
	 * 参数输入：model:Rainier.UI.V2.CompositeModel<br>
	 * 参数输出：无<br>
	 * 函数返回：删除连线model的详细信息<br>
	 * 异常信息：无<br>
	 */
	removeConnection : function(conn,needCommandRequest){
		var _this	   			= this;
		var connList   			= new draw2d.util.ArrayList();
		var deleteConnInfoStack = new draw2d.util.ArrayList();
		var sourcePort			= conn.getSourcePort();
		var targetPort			= conn.getTargetPort();
		
		//当全选删除时,同时存在元件的删除和，连线的删除
		//如果删除了元件,则对应的连线，会解除关联关系，出现没有sourcePort和targetPort的内容。
		//说明该连线已经被删除。直接返回
		if(!sourcePort || !targetPort){
			return null;
		}
		
		//第一步：获取所有的connection
		connList = conn.getBranchConnection();
		
		//第二步：去除重复的连线
		var uniqConnList = this.uniqConnList(connList);
		
		//第三步：删除所有的连线		
		this.deleteConnection(uniqConnList,deleteConnInfoStack);
		
		var newValue 				= {};
		newValue.model				= conn;
		newValue.portList			= null;
		newValue.deleteConnInfoStack= deleteConnInfoStack; 
		newValue.needCommandRequest = needCommandRequest;
		
		var event = Rainier.UI.V2.CompositeModel.MODEL_EVENT_REMOVE_CONNECTION;
		this.firePropertyChange(
				event, 
				null, 
				newValue
		);
		_this.resetConnectionPortValue(sourcePort,targetPort);
		//返回值
		return newValue;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.removePort<br>
	 * 函数功能：删除端口<br>
	 * 参数输出：port:Rainier.UI.V2.AbstractPortModel<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	removePort : function(port,needCommandRequest){
		
		var portIncomings = port.getIncomings().clone(); //端口入度连接
		var portOutgoings = port.getOutgoings().clone(); //端口出度连接	
		
		//删除端口的入度连接
		/*portIncomings.each(function(i,c){
			var cparent = c.getParent();
			cparent.removeConnection(c);
		},false);
		
		//删除端口出度连接
		portOutgoings.each(function(i,c){
			var cparent = c.getParent();
			cparent.removeConnection(c);
		},false);*/
		
		if(port instanceof Rainier.UI.V2.InputPortModel){
			this.inputPorts.remove(port);
		}
		if(port instanceof Rainier.UI.V2.OutputPortModel){
			this.outputPorts.remove(port);
		}
		if(port instanceof Rainier.UI.V2.HybridPortModel){
			this.hybridPorts.remove(port);
		}
		
		var newValue = {};
		newValue.model = port;
		newValue.needCommandRequest = needCommandRequest;
		var event = Rainier.UI.V2.CompositeModel.MODEL_EVENT_REMOVE_PORT;
		this.firePropertyChange(
				event, 
				null, 
				newValue
		);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.addPort<br>
	 * 函数功能：添加端口<br>
	 * 参数输入：port:Rainier.UI.V2.AbstractPortModel<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	addPort : function(port,needCommandRequest){

		port.setParent(this);
		
		if(port instanceof Rainier.UI.V2.InputPortModel){
			this.inputPorts.add(port);
		}
		if(port instanceof Rainier.UI.V2.OutputPortModel){
			this.outputPorts.add(port);
		}
		if(port instanceof Rainier.UI.V2.HybridPortModel){
			this.hybridPorts.add(port);
		}
		
		var newValue = {};
		newValue.model = port;
		newValue.needCommandRequest = needCommandRequest;
		
		var event = Rainier.UI.V2.CompositeModel.MODEL_EVENT_ADD_PORT;
		this.firePropertyChange(
				event, 
				null, 
				newValue
		);
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.getConnections<br>
	 * 函数功能：获取所有连接<br>
	 * 函数返回：draw2d.util.ArrayList<br>
	 * 异常信息：<br>
	 */
	getConnections : function(){
		return this.connections.clone();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.getInputPorts<br>
	 * 函数功能：获取输入端口列表<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	getInputPorts : function(){
		return this.inputPorts.clone();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.getOutputPorts<br>
	 * 函数功能：获取输出端口列表<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	getOutputPorts : function(){
		return this.outputPorts.clone();
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.getHybridPorts<br>
	 * 函数功能：获取混合端口列表<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	getHybridPorts : function(){
		return this.hybridPorts.clone();
	},

	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.getPortByName<br>
	 * 函数功能：根据名称获取端口实例<br>
	 * 参数输入：sName : Port的名字<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	getPortByName : function(sName){
		var find = null;
		var type = '';
		this.inputPorts.each(function(i,p){
			if(p.property.name === sName){
				find = p;
				type = 'input';
			}
		});
		this.outputPorts.each(function(i,p){
			if(p.property.name === sName){
				find = p;
				type = 'output';
			}
		});
		this.hybridPorts.each(function(i,p){
			if(p.property.name === sName){
				find = p;
				type = 'hybrid';
			}
		});
		
		return {port:find,type:type};
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel.deleteConnection<br>
	 * 删除及对应的恢复思路：
	 * 所有需要删除的连线，先删除没有子元素的连线（即，连线上没有长jointModel的连线）
	 * 同时对每一条连线，进行检测，
	 * 如：source端口为jointModel的连线，或者target端口为jointModel的连线，或者两者都是jointModel的连线
	 *    则删除对应的jointModel，
	 *    删除的过程中，哪些长有jointModel子元素的连线，会移除对应的jointModel，变为没有子元素的连线
	 * 重复这一过程，完成所有连线的删除工作。
	 * 对上术过程，记录对应的顺序，和删除记录，供恢复时使用。
	 * 函数功能：删除连线所有的连线内容<br>
	 * 参数输入：connList		 : 需要删除的连线数组<br>
	 * 参数输出：connInfoStack	 : 删除连线的信息数组<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	deleteConnection : function(connList,connInfoStack){
		var _this = this;
		while(connList.getSize()){
			for(var i = 0;i<connList.getSize();i++){
				var conn 		= connList.get(i);
				var jointModels = conn.getChildren();
				
				//保存没有孩子的连线
				if(!jointModels.length){
					//把删除的信息，保存在堆栈中
					var connInfo		= conn.encapsulateConnInfo();
					connInfoStack.push(connInfo);
					
					//根据连线类型，删除连线
					var connType  		= connInfo.connType;
					var connModel   	= connInfo.connModel;
					var sourceModel  	= connInfo.sourceModel;
					var targetModel		= connInfo.targetModel;
					
					var currentConn		= connModel.connection;

					//解除关联关系
					currentConn.detachSourcePortAndTargetPort();
					
					//删除连线
					_this.connections.remove(currentConn);
					
					//根据jointModel是否存在，进行jointModel的删除
					if(sourceModel){
						var jointModel = sourceModel.jointModel;
						_this._removeJointModel(jointModel);
					}
					if(targetModel){
						var jointModel = targetModel.jointModel;
						_this._removeJointModel(jointModel);
					}
					
					var newValue = {};
					newValue.model = conn;
					newValue.needCommandRequest = null;
					
					var event = Rainier.UI.V2.CompositeModel.MODEL_EVENT_REMOVE_CONNECTION;
					_this.firePropertyChange(
							event, 
							null, 
							newValue
					);
					
					
					connList.removeElementAt(i);
					i--;
				}
			}
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.CompositeModel._removeJointModel<br>
	 * 函数功能：删除连线的 的sourceModel,或者targetModel<br>
	 * 参数输入：jointModel : 需要删除的jointModel<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	 _removeJointModel:function(jointModel){
		jointPort 	  = jointModel.getHybridPorts().get(0);
		var incoming  = jointPort.getIncomings();
		var outgoing  = jointPort.getOutgoings();
		var size 	  = incoming.getSize() + outgoing.getSize();
		if(size<1){
			//说明当前节点可以删除
			var jointModelParent = jointModel.getParent();
			if(jointModelParent){
				jointModelParent.removeChildModel(jointModel);
			}
		}
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.uniqConnList<br>
	 * 函数功能：去重：去除ConnList中重复出现的连线<br>
	 * 参数输入：connList: 所有的连线的数组<br>
	 * 参数输出：无<br>
	 * 函数返回：uniqConnList<br>
	 * 异常信息：无<br>
	 */
	 uniqConnList:function(connList){
		 
		 var uniqConnList = new draw2d.util.ArrayList();
		 var connIdArray  = new draw2d.util.ArrayList();
		 
		 connList.each(function(index,conn){
			 var connId = conn.getUuid();
			 //如果数组中不存在当前的id
			 if(connIdArray.indexOf(connId) === -1){
				 connIdArray.add(connId);
				 uniqConnList.add(conn);
			 }
		 })
		 
		 return uniqConnList;
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.setConnectionPortValue<br>
	 * 函数功能：创建连线时，计算生成对应port的Value值<br>
	 * 参数输入：sourceModel:连线的源端口<br>
	 * 参数输入：targetModel:连线的目标端口<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 * 
	 */
	 setConnectionPortValue : function(sourceModel,targetModel){
		var canvasContactPortList  = this.context.canvasContactPortList;
		var numberGenerator		   = this.context.lineNumberGenerator;
		if(canvasContactPortList.getSize()>0){
			//大于0，说明界面已经存在连线
			var portModelConcactList1 = this.getPortModelConcactList(sourceModel,canvasContactPortList);
			var portModelConcactList2 = this.getPortModelConcactList(targetModel,canvasContactPortList);
			if(portModelConcactList1 && portModelConcactList2){
				//同时存在
				var isEqules =  this.isPortListEquals(portModelConcactList1,portModelConcactList2);
				if(isEqules){
					//nothing todo;
				}else{					
				    var sourceNodeValue = sourceModel.getProperty().modelProperty.node;
				    var targetNodeValue = targetModel.getProperty().modelProperty.node;
									
					if(sourceNodeValue === 0 && targetNodeValue === 0){
						//第一步：不用对连线的node值进行操作
						//第二步：把两组数据连接为一组，把被合并的一组删除
						/*portModelConcactList1.addAll(portModelConcactList2);
						canvasContactPortList.remove(portModelConcactList2);*/
					}
					if(sourceNodeValue === 0 && targetNodeValue !== 0){
						//第一步 ： 把另一组的值，全部赋值为0;
						portModelConcactList2.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						});
						
						numberGenerator.removeNumber(targetNodeValue);						
					}
					if(sourceNodeValue !== 0 && targetNodeValue === 0){
						//第一步 ： 把另一组的值，全部赋值为0;
						portModelConcactList1.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						});
						
						numberGenerator.removeNumber(sourceNodeValue);						
					}
					if(sourceNodeValue !== 0 && targetNodeValue !== 0){
						var nodeValue = 0;
						if(sourceNodeValue < targetNodeValue){
							nodeValue = sourceNodeValue;
							numberGenerator.removeNumber(targetNodeValue);
							
							portModelConcactList2.each(function(index,portModel){
								portModel.getProperty().modelProperty.node = nodeValue;
							});
						}else{
							nodeValue = targetNodeValue;
							numberGenerator.removeNumber(sourceNodeValue);	
							
							portModelConcactList1.each(function(index,portModel){
								portModel.getProperty().modelProperty.node = nodeValue;
							});						
						}
					}
					//第二步：把两组合并为一组,把被合并的一组删除
					portModelConcactList1.addAll(portModelConcactList2);
					canvasContactPortList.remove(portModelConcactList2);
				}
			}
			if(portModelConcactList1 && !portModelConcactList2){
			    //一个存在，另一个不存在
				var nodeValue 		  = sourceModel.getProperty().modelProperty.node;
				var targetModelParent = targetModel.getParent();
				if(targetModelParent instanceof Rainier.UI.V2.DeviceModel){
					var isGround = this.isGroundDeviceModel(targetModelParent);
					if(nodeValue === 0){
						//此处直接把port的值赋值为零 ，并把该port添加到portList中
						targetModel.getProperty().modelProperty.node = 0;						
					}
					if(nodeValue !==0 && isGround){
						targetModel.getProperty().modelProperty.node = 0;
						portModelConcactList1.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						});
						numberGenerator.removeNumber(nodeValue);
					}
					if(nodeValue !==0 && !isGround){
						targetModel.getProperty().modelProperty.node = nodeValue;
					}
					//把 孤立的port添加到portList中
					portModelConcactList1.add(targetModel);
				}
				if(targetModelParent instanceof Rainier.UI.V2.JointModel){
					var connectionModel 	= targetModel.getParent().getParent();
					var sourcePortModel 	= connectionModel.getSourcePort();
					var sourcePortList		= this.getPortModelConcactList(sourcePortModel,canvasContactPortList);
					if (!sourcePortList) {
						return;
					}
					if(sourcePortList.getSize()<=0){
						throw new Error("当前连线的sourcePortList不可能为空，请review程序，检查错误");
					}
					var sourcePortNodeValue = sourcePortModel.getProperty().modelProperty.node;
					if(nodeValue === 0 && sourcePortNodeValue === 0){
						targetModel.getProperty().modelProperty.node = 0;
					}
					if(nodeValue === 0 && sourcePortNodeValue !==0){
						targetModel.getProperty().modelProperty.node = 0;
						sourcePortList.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						})
						numberGenerator.removeNumber(sourcePortNodeValue);	
					}	
					if(nodeValue !==0 && sourcePortNodeValue ===0){
						targetModel.getProperty().modelProperty.node = 0;
						
						portModelConcactList1.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						});
						numberGenerator.removeNumber(nodeValue);
					}
					if(nodeValue !==0 && sourcePortNodeValue !==0){
						var usedNodeValue = 0;
						if(nodeValue < sourcePortNodeValue){
							usedNodeValue = nodeValue;
							targetModel.getProperty().modelProperty.node = usedNodeValue;
							sourcePortList.each(function(index,portModel){
								portModel.getProperty().modelProperty.node = usedNodeValue;
							})
							numberGenerator.removeNumber(sourcePortNodeValue);
						}else{
							usedNodeValue = sourcePortNodeValue;
							targetModel.getProperty().modelProperty.node = usedNodeValue;
							portModelConcactList1.each(function(index,portModel){
								portModel.getProperty().modelProperty.node = usedNodeValue;
							});
							numberGenerator.removeNumber(nodeValue);
						}
					}
					portModelConcactList1.add(targetModel);
					portModelConcactList1.addAll(sourcePortList);
					canvasContactPortList.remove(sourcePortList);
				}
			}
			if(!portModelConcactList1 && portModelConcactList2){
				//一个存在，另一个不存在
				var nodeValue 		    = targetModel.getProperty().modelProperty.node;
				var sourceModelParent   = sourceModel.getParent();
				var sourceModelProperty = sourceModel.getProperty().modelProperty;
				if(sourceModelParent instanceof Rainier.UI.V2.DeviceModel){
					var isGround = this.isGroundDeviceModel(sourceModelParent);
					if(nodeValue === 0){
						sourceModelProperty.node = 0;
					}
					if(nodeValue !== 0 && isGround){
						sourceModelProperty.node = 0;
						portModelConcactList2.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						});
						numberGenerator.removeNumber(nodeValue);
					}
					if(nodeValue !== 0 && !isGround){
						sourceModelProperty.node = nodeValue;
					}
					portModelConcactList2.add(sourceModel);
				}
				if(sourceModelParent instanceof Rainier.UI.V2.JointModel){
					var connectionModel 	= sourceModel.getParent().getParent();
					var sourcePortModel 	= connectionModel.getSourcePort();
					var sourcePortList		= this.getPortModelConcactList(sourcePortModel,canvasContactPortList);
					if (!sourcePortList) {
						return;
					}
					if(sourcePortList.getSize()<=0){
						throw new Error("当前连线的sourcePortList不可能为空，请review程序，检查错误");
					}
					var sourcePortNodeValue = sourcePortModel.getProperty().modelProperty.node;
					if(nodeValue === 0 && sourcePortNodeValue === 0){
						sourceModelProperty.node = 0;
					}
					if(nodeValue === 0 && sourcePortNodeValue !==0){
						sourceModelProperty.node = 0;
						sourcePortList.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						})
						numberGenerator.removeNumber(sourcePortNodeValue);	
					}	
					if(nodeValue !==0 && sourcePortNodeValue ===0){
						sourceModelProperty.node = 0;
						
						portModelConcactList2.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						});
						numberGenerator.removeNumber(nodeValue);
					}
					if(nodeValue !==0 && sourcePortNodeValue !==0){
						var usedNodeValue = 0;
						if(nodeValue < sourcePortNodeValue){
							usedNodeValue = nodeValue;
							sourceModelProperty.node = usedNodeValue;
							sourcePortList.each(function(index,portModel){
								portModel.getProperty().modelProperty.node = usedNodeValue;
							})
							numberGenerator.removeNumber(sourcePortNodeValue);
						}else{
							usedNodeValue = sourcePortNodeValue;
							sourceModelProperty.node = usedNodeValue;
							portModelConcactList2.each(function(index,portModel){
								portModel.getProperty().modelProperty.node = usedNodeValue;
							});
							numberGenerator.removeNumber(nodeValue);
						}
					}
					portModelConcactList2.add(targetModel);
					portModelConcactList2.addAll(sourcePortList);
					canvasContactPortList.remove(sourcePortList);
				}
			}
			if(!portModelConcactList1 && !portModelConcactList2){
				//两个都不存在
				var sourceModelParent = sourceModel.getParent();
				var targetModelParent = targetModel.getParent();
				if(sourceModelParent instanceof Rainier.UI.V2.DeviceModel &&
						targetModelParent instanceof Rainier.UI.V2.DeviceModel){
					var isGround1  = this.isGroundDeviceModel(sourceModelParent);
					var isGround2  = this.isGroundDeviceModel(targetModelParent);
					var portList   = new draw2d.util.ArrayList();
					var lineNumber = 0;
					if(isGround1 || isGround2){
						lineNumber = 0;
					}else{
						lineNumber = numberGenerator.generateNumber();
					}
					sourceModel.getProperty().modelProperty.node = lineNumber;
					targetModel.getProperty().modelProperty.node = lineNumber;
					portList.add(sourceModel);
					portList.add(targetModel);
					
					canvasContactPortList.add(portList);				
				}
				
				if(sourceModelParent instanceof Rainier.UI.V2.DeviceModel &&
						targetModelParent instanceof Rainier.UI.V2.JointModel){
					//处理jointModel
					var connectionModel 	= targetModel.getParent().getParent();
					var sourcePortModel 	= connectionModel.getSourcePort();
					var sourcePortList		= this.getPortModelConcactList(sourcePortModel,canvasContactPortList);
					if (!sourcePortList) {
						return;
					}
					if(sourcePortList.getSize()<=0){
						throw new Error("当前连线的sourcePortList不可能为空，请review程序，检查错误");
					}
					var sourcePortNodeValue = sourcePortModel.getProperty().modelProperty.node;
					//处理sourceModel;
					var isGround 			= this.isGroundDeviceModel(sourceModelParent);
					var sourceModelProperty = sourceModel.getProperty().modelProperty;
					var targetModelProperty = targetModel.getProperty().modelProperty;
					if(sourcePortNodeValue === 0){
						sourceModelProperty.node = 0 ;
						targetModelProperty.node = 0 ;
					}
					if(sourcePortNodeValue !== 0 && isGround){
						targetModelProperty.node = 0 ;
						sourceModelProperty.node = 0 ;
						sourcePortList.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						});
						numberGenerator.removeNumber(sourcePortNodeValue);
					}
					if(sourcePortNodeValue  !== 0 && !isGround){
						sourceModelProperty.node = sourcePortNodeValue ;
						targetModelProperty.node = sourcePortNodeValue ;
					}
					sourcePortList.add(sourceModel);
					sourcePortList.add(targetModel);
				}
				
				if(sourceModelParent instanceof Rainier.UI.V2.JointModel &&
						targetModelParent instanceof Rainier.UI.V2.DeviceModel){
					//处理jointModel
					var connectionModel 	= sourceModel.getParent().getParent();
					var sourcePortModel 	= connectionModel.getSourcePort();
					var sourcePortList		= this.getPortModelConcactList(sourcePortModel,canvasContactPortList);
					if (!sourcePortList) {
						return;
					}
					if(sourcePortList.getSize()<=0){
						throw new Error("当前连线的sourcePortList不可能为空，请review程序，检查错误");
					}
					var sourcePortNodeValue = sourcePortModel.getProperty().modelProperty.node;
					//处理targetModel
					var isGround			= this.isGroundDeviceModel(targetModelParent);
					var sourceModelProperty = sourceModel.getProperty().modelProperty;
					var targetModelProperty = targetModel.getProperty().modelProperty;
					if(sourcePortNodeValue === 0){
						sourceModelProperty.node = 0 ;
						targetModelProperty.node = 0 ;
					}
					if(sourcePortNodeValue !== 0 && isGround){
						sourceModelProperty.node = 0 ;
						targetModelProperty.node = 0 ;
						sourcePortList.each(function(index,portModel){
							portModel.getProperty().modelProperty.node = 0;
						});
						numberGenerator.removeNumber(sourcePortNodeValue);
					}
					if(sourcePortNodeValue !== 0 && !isGround){
						sourceModelProperty.node = sourcePortNodeValue ;
						targetModelProperty.node = sourcePortNodeValue ;
					}
					sourcePortList.add(sourceModel);
					sourcePortList.add(targetModel);
				}
				if(sourceModelParent instanceof Rainier.UI.V2.JointModel &&
						targetModelParent instanceof Rainier.UI.V2.JointModel){
					//此处不会出现
				}
			}
		}else{
			//等于0，说明此时创建的连线是第一条连线，且此时只能是 元件到元件的连线
			var sourceModelParent = sourceModel.getParent();
			var targetModelParent = targetModel.getParent();
			
			var isGround1	= this.isGroundDeviceModel(sourceModelParent);
			var isGround2	= this.isGroundDeviceModel(targetModelParent);
			var portList    = new draw2d.util.ArrayList();
			var lineNumber	= 0;
			if(isGround1 || isGround2){
				lineNumber = 0;
			}else{
				lineNumber = numberGenerator.generateNumber();				
			}
			sourceModel.getProperty().modelProperty.node = lineNumber;
			targetModel.getProperty().modelProperty.node = lineNumber;
			
			portList.add(sourceModel);
			portList.add(targetModel);
			canvasContactPortList.add(portList);
			
		}
		//刷新nodeLabel;
		this.getConnections().each(function(index,conn){
    		conn.changeNodeLabel(true,false);
    	})
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.isGroundDeviceModel<br>
	 * 函数功能：判断deviceModel是否是Ground<br>
	 * 参数输入：model ： 需要判断的deviceModel<br>
	 * 参数输出：无<br>
	 * 函数返回：boolean ： true，说明是Ground；false，说明不是Ground<br>
	 * 异常信息：无<br>
	 */
	 isGroundDeviceModel : function(deviceModel){
		var name = deviceModel.getProperty().modelProperty.typeName;
		if(name && (name.toLowerCase() === 'ground')){
			return true;
		}
		return false; 
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.isPortListEquals<br>
	 * 函数功能：判断连个portList是否相同，<br>
	 * 参数输入：portList1 : 第一个PortList<br>
	 * 参数输入：portList2 : 第二个PortList<br>
	 * 参数输出：无<br>
	 * 函数返回：boolean：true，相同；false，不相同<br>
	 * 异常信息：无<br>
	 */
	 isPortListEquals : function(portList1,portList2){
		 var size1 = portList1.getSize();
		 var size2 = portList2.getSize();
		 if(size1 !== size2){
			 return false;
		 }
		 for(var i = 0 ; i < size1 ; i++){
			 var portModel1 = portList1.get(i);
			 var portModel2 = portList2.get(i);
			 if(portModel1.getUuid() !== portModel2.getUuid()){
				 return false;
			 }
		 }
		 return true;
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.getPortModelConcactList<br>
	 * 函数功能：检索创建连线的连个portModel,是否已经存在在canvasContactPortList中<br>
	 * 参数输入：portModel				:需要查找的portModel<br>
	 * 参数输入：canvasContactPortList : canvas中所有的portList数组 的数组容器<br>
	 * 参数输出：无<br>
	 * 函数返回：portList : 查找到的portList,或者为null<br>
	 * 异常信息：无<br> 
	 */
	 getPortModelConcactList : function(portModel,canvasConactPortList){
		 var existPortList  = null;
		 canvasConactPortList.each(function(index,portList){
			var existFlag = false;
			portList.each(function(index,model){
				if(model.getUuid() === portModel.getUuid()){
					existFlag = true;
					return false;
				}
			});
			if(existFlag){
				existPortList = portList;
				return false;
			}
		 });
		 if(existPortList){
			 return existPortList;
		 }else{
			 return null;
		 }
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.getPortList<br>
	 * 函数功能：通过一点获取其在canvas中所有与其相关联的port，行成一个portList<br>
	 * 参数输入：portModel  :进行检索的portModel<br>
	 * 参数输入：connectList:canvas中所有的连线<br>
	 * 参数输出：portList   :把所有的portList传递出去<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	 getPortList : function(_this,portModel,portList,connectList){
		 var args	   = arguments;
		 _this.traversalPort(portModel,function(port,conn){
			 var index = connectList.indexOf(conn);
	         if(index>=0){
	        	 connectList.removeElementAt(index);
	         }
	         else{
	        	 return false;
	         }
			 var sourcePort = conn.getSourcePort();
			 var targetPort = conn.getTargetPort();
			 var otherPort  = sourcePort;
			 if(sourcePort === portModel){
				 otherPort = targetPort;
			 }
			 if(otherPort){
				 if(portList.indexOf(otherPort)<0){
					 portList.add(otherPort);
					 args.callee(_this,otherPort,portList,connectList);
					 if(otherPort.getParent() instanceof Rainier.UI.V2.JointModel){
							var sourcePort  = otherPort.getParent().getParent().sourcePort;
							if(portList.indexOf(sourcePort) < 0){
								portList.push(sourcePort);
								args.callee(_this,sourcePort,portList,connectList);
							}
						}
				 }
			 }
			 if(conn.hasChildren()){
					var children = conn.getChildren();
					$.each(children,function(index,child){
						if(child instanceof Rainier.UI.V2.JointModel){
							var hybrid  = child.getHybridPorts().get(0);
							if(portList.indexOf(hybrid) < 0){
								portList.push(hybrid);
								args.callee(_this,hybrid,portList,connectList);
							}
						}
					});
				}
		 });
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CircuitParser.traversalPort<br>
	 * 函数功能：遍历端口，获取所有连线，并执行回调函数<br>
	 * 参数输入：port：Rainier.UI.V2.AbstractPortModel<br>
	 * 参数输入：callback：回调函数<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
    traversalPort : function(port,callback){
    	if(port && port instanceof Rainier.UI.V2.AbstractPortModel){
    		var incomings = port.getIncomings();
    		var outgoings = port.getOutgoings();
    		var conns	  = incomings.addAll(outgoings);
    		conns.each(function(j,c){
    			callback(port,c);
    		});
    	}
    },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.resetConnectionPortValue<br>
	 * 函数功能：删除连线时，重置和删除连线相关的 连线port的Value值<br>
	 * 参数输入：sourceModel : 连线的源端口<br>
	 * 参数输出：targetModel : 连线的目标端口<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	 resetConnectionPortValue : function(sourceModel,targetModel){
		if(!sourceModel || !targetModel){
			throw new Error("删除连线信息有错误，请注意检测");
		}
		var _this				   = this;
		var canvasContactPortList  = this.context.canvasContactPortList;
		var numberGenerator		   = this.context.lineNumberGenerator;
		var currentPortList		   = new draw2d.util.ArrayList();
		var connectionList		   = this.getConnections().clone();
		//实时计算当前port的portList
		this.getPortList(_this,sourceModel,currentPortList,connectionList);
		this.addPortToPortList(sourceModel,currentPortList);
		
		//从静态的canvasContactPortList中获取和此时删除port有关的portList
		var staticPortList		   = this.getPortModelConcactList(sourceModel,canvasContactPortList);
		if(!staticPortList || !currentPortList){
			return;
		}
		var isEquals			   = this.isPortListEquals(currentPortList,staticPortList);
		
		//移除需要删除连线的lineNumber;
		var nodeValue			   = sourceModel.getProperty().modelProperty.node;
		if(nodeValue>0){			
			numberGenerator.removeNumber(nodeValue);
		}
		
		if(!isEquals){
			var portListCopy = staticPortList.clone();
			
			this.removePortList(staticPortList,canvasContactPortList);
			
			var connsList 		= this.getConnections().clone();
			var devicePortList	= new draw2d.util.ArrayList();
			portListCopy.each(function(index,port){
				if(port.getParent() instanceof Rainier.UI.V2.DeviceModel){
					devicePortList.add(port);
				}
			});
			while(devicePortList.getSize() > 0){
				var port 	  = devicePortList.get(0);
				var portList  = new draw2d.util.ArrayList();
				this.getPortList(_this,port,portList,connsList);
				this.addPortToPortList(port,portList);
				portList.each(function(index,portModel){
					_this.removePortFormPortList(portModel,devicePortList);
				});
				if(portList.getSize()>1){
					var isGround  = false;
					portList.each(function(index,portModel){
						var modelParent = portModel.getParent();
						if(modelParent instanceof Rainier.UI.V2.DeviceModel){
							isGround = _this.isGroundDeviceModel(modelParent);
							if(isGround){
								return false;
							}
						}
					});
					var lineNumber = 0;
					if(isGround){
						lineNumber = 0;
					}else{
						lineNumber = numberGenerator.generateNumber();
					}
					portList.each(function(index,portModel){						
						portModel.getProperty().modelProperty.node = lineNumber;
					});
					canvasContactPortList.add(portList);
				}else{
					portList.each(function(index,portModel){
						portModel.getProperty().modelProperty.node = -1;
					});
				}
			}
		}
		
		//刷新nodeLabel;
		this.getConnections().each(function(index,conn){
    		conn.changeNodeLabel(true,false);
    	})
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.addPortToPortList<br>
	 * 函数功能：向一个固定的portList中添加port。<br>
	 * 参数输入：port		：需要添加的port<br>
	 * 参数输入：portList	：添加数据的portList<br>
	 * 参数输出：<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	 addPortToPortList : function(port,portList){
		 var existFlag = false;
		 portList.each(function(index,portModel){
			if(port.getUuid() === portModel.getUuid()){
				existFlag = true;
				return false;
			}
		 });
		 if(!existFlag){
			 portList.add(port);
		 }
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.removePortFormPortList<br>
	 * 函数功能：删除portList中的portModel<br>
	 * 参数输入：portModel:需要删除的portModel<br>
	 * 参数输出：portList :portList数组<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	 removePortFormPortList : function(portModel,portList){
		 var portModelIndex = -1;
		 portList.each(function(index,port){
			 if(portModel.getUuid() === port.getUuid()){
				 portModelIndex = index;
				 return false;
			 }
		 });
		 if(portModelIndex>=0){
			 portList.removeElementAt(portModelIndex);
		 }
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.removePortList<br>
	 * 函数功能：从全局portList中删除指定的portList<br>
	 * 参数输入：portList		 :需要删除的portList<br>
	 * 参数输入：globlePortList :全局的portList<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	 removePortList : function(portList,globlePortList){
		 var _this		   = this;
		 var portListIndex = -1;
		 globlePortList.each(function(index,list){
			 var isEquals = _this.isPortListEquals(list,portList);
			 if(isEquals){
				 portListIndex = index;
			 }
		 });
		 if(portListIndex >= 0){
			 globlePortList.removeElementAt(portListIndex);
		 }
	 },
	 
	 /**
	 * 函数名称：Rainier.UI.V2.CompositeModel.showConnectionsLabel<br>
	 * 函数功能：是否显示界面连线的labelNode<br>
	 * 参数输入：无<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	 showConnectionsLabel : function(){ 	   
		 var jointPortUsed = this.context.menuItemUsedInfo.jointPortUsed;
		 if(!jointPortUsed){
			 var connections = this.context.getRootModel().getConnections();
			 connections.each(function(index,conn){
				 conn.changeNodeLabel(true,false);
			 });
		 }
	  },
});

/**
 * 函数名称：Rainier.Basic.CompositeObject.reursiveRemoveChild<br>
 * 函数功能：递归遍历所有子对象<br>
 * 参数输入：objRoot	Rainier.Basic.CompositeObject实例对象<br>
 * 参数输入：func:function(obj){};在删除对象前执行
 * 函数返回：搜索到的om.rainier.classes.CompositeObject实例对象<br>
 * 异常信息：无<br>
 */
Rainier.UI.V2.CompositeModel.reursiveRemoveChildModel = function(objRoot,func){
	var objArray = objRoot.getChildren();
	for ( var key in objArray) {
		if(objArray[key].hasChildren()){
			Rainier.UI.V2.CompositeModel.reursiveRemoveChildModel(objArray[key],func);
		}else{
			if(objArray[key].getParent()){
				if(func){
					func(objArray[key]);						
				}
				objArray[key].getParent().removeChildById(objArray[key].getUuid());
			}
		}			
	}
	
	if(objRoot.getParent()){
		if(func){
			func(objRoot);				
		}
		objRoot.getParent().removeChildById(objRoot.getUuid());
	}
	
};

Rainier.UI.V2.CompositeModel.MODEL_EVENT_ADD_PORT 			= "model event add port";			//添加端口事件
Rainier.UI.V2.CompositeModel.MODEL_EVENT_REMOVE_PORT		= "model event remove port";		//删除端口事件
Rainier.UI.V2.CompositeModel.MODEL_EVENT_ADD_CONNECTION 	= "model event add connection";		//添加连接事件
Rainier.UI.V2.CompositeModel.MODEL_EVENT_REMOVE_CONNECTION 	= "model event remove connection";	//删除连接事件